package com.osce.system.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.doudou.core.container.ListUtil;
import com.doudou.core.container.MapUtil;
import com.doudou.core.lang.ObjUtil;
import com.doudou.core.throwable.GlobalException;
import com.douodu.excel.status.ImportStatus;
import com.osce.common.annotation.DataScope;
import com.osce.common.core.entity.entity.SysRole;
import com.osce.common.core.entity.entity.SysUser;
import com.osce.common.core.entity.vo.StudentExcelVo;
import com.osce.common.exception.ServiceException;
import com.osce.common.utils.SecurityUtils;
import com.osce.common.utils.StringUtils;
import com.osce.common.utils.bean.BeanValidators;
import com.osce.interfaces.basic.IBasicBaseService;
import com.osce.interfaces.basic.IBasicSchoolService;
import com.osce.interfaces.system.*;
import com.osce.system.mapper.StudentMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.Validator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户 业务层处理
 *
 * @author ruoyi
 */
@Service
public class StudentServiceImpl implements IStudentService {

    private static final Logger log = LoggerFactory.getLogger(StudentServiceImpl.class);

    @Resource
    private StudentMapper studentMapper;
    @Resource
    private ISysConfigService configService;
    @Resource
    private ISysDeptService deptService;
    @Resource
    private ISysUserService userService;
    @Resource
    private IBasicBaseService baseService;
    @Resource
    private IBasicSchoolService schoolService;
    @Resource
    protected Validator validator;
    @Resource
    private ISysRoleService roleService;

    /**
     * 根据条件分页查询用户列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<SysUser> selectList(SysUser user) {
        if (user != null && "2".equals(user.getStatus())) {
            user.setDelFlag("2"); // 设置删除标志为2（被删除状态）
            user.setStatus(null); // 清空状态条件
        } else if (user != null && user.getDelFlag() == null) {
            // 其他情况默认不显示被删除的数据
            user.setDelFlag("0"); // 设置删除标志为0（正常状态）
        }
        return studentMapper.selectStudentList(user);
    }

     /**
     * 平板端获取组织下学生列表
     *
     * @param deptId 用户信息
     * @return 用户信息集合信息
     */
    @Override
    public List<SysUser> selectSlabList(Long deptId) {
        SysUser user = new SysUser();
        user.setDeptId(deptId);
        // 设置用户类型为2（学生）
        user.setUserType("2");
        // 设置删除标志为0（未删除）
        user.setDelFlag("0");
        // 设置状态为0（正常状态）
        user.setStatus("0");
        return studentMapper.selectStudentList(user);
    }


    /**
     * 验证身份证号格式
     * @param identity 身份证号
     * @return 是否有效
     */
    private boolean isValidIdentity(String identity) {
        // 简单的身份证号格式验证：18位，最后一位可能是X
        String regex = "^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";
        return identity.matches(regex);
    }
    /**
     * 导入用户数据
     *
     * @param userList        用户数据列表
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName        操作用户
     * @return 结果
     */
    @Override
    public String importStudent(List<StudentExcelVo> userList, Boolean isUpdateSupport, String operName) {
        if (ListUtil.isEmpty(userList) || userList.size() == 0) {
            throw new ServiceException("导入用户数据不能为空！");
        }
        Map<String, Long> baseMap = baseService.selectAllIdToMap();
        Map<String, Long> schoolMap = schoolService.selectAllIdToMap();
        Map<String, Long> deptMap = deptService.selectAllIdToMap();
        SysUser user;
        String password = configService.selectConfigValueByKey("sys.user.initPassword");
        ImportStatus importStatus = new ImportStatus();//提示语句对象
        //查询学生角色
        List<SysRole> studentRoles = roleService.selectRoleList(SysRole.builder().roleKey("student").build());
        Long[] studentRoleIds = studentRoles.stream().map(SysRole::getRoleId).toArray(o-> new Long[studentRoles.size()]);
        int index = 1;
        for (StudentExcelVo student : userList) {
            try {
                // 校验必填项
                if (StringUtils.isEmpty(student.getNickName())) {
                    throw new ServiceException("姓名不能为空");
                }
                if (StringUtils.isEmpty(student.getSex())) {
                    throw new ServiceException("性别不能为空");
                }
                if (StringUtils.isEmpty(student.getIdentity())) {
                    throw new ServiceException("身份证号不能为空");
                }
                // 校验身份证号格式
                if (!isValidIdentity(student.getIdentity())) {
                    throw new ServiceException("身份证号格式不正确");
                }
                if (StringUtils.isEmpty(student.getDeptName())) {
                    throw new ServiceException("所属科室不能为空");
                }
                if (StringUtils.isEmpty(student.getOrganizationalCategory())) {
                    throw new ServiceException("总支不能为空");
                }
                if (StringUtils.isEmpty(student.getDutyTitle())) {
                    throw new ServiceException("部职别不能为空");
                }
                if (student.getPersonnelCategoryId() == null) {
                    throw new ServiceException("人员类别不能为空");
                }

                // 验证是否存在这个用户
                SysUser selectUser = userService.selectUserByUserName(student.getUserName());
                if (ObjectUtil.isEmpty(selectUser)) {
                    // 验证身份证号唯一性
                    if (StringUtils.isNotEmpty(student.getIdentity())) {
                        SysUser identityUser = userService.selectUserByIdentity(student.getIdentity());
                        if (ObjectUtil.isNotEmpty(identityUser)) {
                            throw new ServiceException("身份证号" + student.getIdentity() + "已存在");
                        }
                    }
                    BeanValidators.validateWithException(validator, student);
                    user = BeanUtil.copyProperties(student, SysUser.class);
                    user.setDeptId(MapUtil.get(deptMap, student.getDeptName()));
                    user.setPassword(SecurityUtils.encryptPassword(password));
                    user.setCreateBy(operName);
                    // 设置用户类型为学生
                    user.setUserType("2");
                    //用户基础数据
                    user.setUserInfo(userService.createUserInfo(student, baseMap, schoolMap));

                    // 创建军人信息对象并设置属性
                    if (student.getNation() != null || student.getNativePlace() != null ||
                            student.getEnlistmentTime() != null || student.getPartyJoiningTime() != null ||
                            student.getEnlistmentPlace() != null || student.getEducationId() != null || student.getDegreeId() != null ||
                            student.getBloodType() != null || student.getPersonnelCategoryId() != null ||
                            student.getSecurityCardNo() != null || student.getMilitaryIdNo() != null ||
                            student.getOrganizationalCategory() != null || student.getDutyTitle() != null) {
                        com.osce.common.core.entity.entity.SysMilitaryUser militaryUser = new com.osce.common.core.entity.entity.SysMilitaryUser();
                        militaryUser.setNation(student.getNation());
                        militaryUser.setNativePlace(student.getNativePlace());
                        militaryUser.setEnlistmentTime(student.getEnlistmentTime());
                        militaryUser.setPartyJoiningTime(student.getPartyJoiningTime());
                        militaryUser.setEnlistmentPlace(student.getEnlistmentPlace());
                        militaryUser.setEducationId(student.getEducationId());
                        militaryUser.setDegreeId(student.getDegreeId());
                        militaryUser.setBloodType(student.getBloodType());
                        militaryUser.setPersonnelCategoryId(student.getPersonnelCategoryId());
                        militaryUser.setSecurityCardNo(student.getSecurityCardNo());
                        militaryUser.setMilitaryIdNo(student.getMilitaryIdNo());
                        militaryUser.setOrganizationalCategory(student.getOrganizationalCategory());
                        militaryUser.setDutyTitle(student.getDutyTitle());
                        user.setMilitaryUser(militaryUser);
                    }

                    user.setRoleIds(studentRoleIds);
                    userService.insertUser(user);
                    // 简化成功消息，只包含账户信息和导入状态
                    String account = StringUtils.isNotEmpty(student.getUserName()) ? student.getUserName() : student.getNickName();
                    String successMsg = "账户:" + account + " ,导入成功";
                    importStatus.addSuccessMsg(index, successMsg);
                } else if (isUpdateSupport) {
                    // 验证身份证号唯一性（排除当前用户）
                    if (StringUtils.isNotEmpty(student.getIdentity())) {
                        SysUser identityUser = userService.selectUserByIdentity(student.getIdentity());
                        if (ObjectUtil.isNotEmpty(identityUser) && !identityUser.getUserId().equals(selectUser.getUserId())) {
                            throw new ServiceException("身份证号" + student.getIdentity() + "已存在");
                        }
                    }
                    BeanValidators.validateWithException(validator, student);
                    user = BeanUtil.copyProperties(student, SysUser.class);
                    userService.checkUserAllowed(selectUser);
                    userService.checkUserDataScope(selectUser.getUserId());
                    user.setDeptId(MapUtil.get(deptMap, student.getDeptName()));
                    user.setUserId(selectUser.getUserId());
                    user.setUpdateBy(operName);
                    // 设置用户类型为学生
                    user.setUserType("2");
                    //用户基础数据
                    user.setUserInfo(userService.createUserInfo(student, baseMap, schoolMap));

                    // 创建军人信息对象并设置属性
                    if (student.getNation() != null || student.getNativePlace() != null ||
                            student.getEnlistmentTime() != null || student.getPartyJoiningTime() != null ||
                            student.getEnlistmentPlace() != null || student.getEducationId() != null || student.getDegreeId() != null ||
                            student.getBloodType() != null || student.getPersonnelCategoryId() != null ||
                            student.getSecurityCardNo() != null || student.getMilitaryIdNo() != null ||
                            student.getOrganizationalCategory() != null || student.getDutyTitle() != null) {
                        com.osce.common.core.entity.entity.SysMilitaryUser militaryUser = new com.osce.common.core.entity.entity.SysMilitaryUser();
                        militaryUser.setNation(student.getNation());
                        militaryUser.setNativePlace(student.getNativePlace());
                        militaryUser.setEnlistmentTime(student.getEnlistmentTime());
                        militaryUser.setPartyJoiningTime(student.getPartyJoiningTime());
                        militaryUser.setEnlistmentPlace(student.getEnlistmentPlace());
                        militaryUser.setEducationId(student.getEducationId());
                        militaryUser.setDegreeId(student.getDegreeId());
                        militaryUser.setBloodType(student.getBloodType());
                        militaryUser.setPersonnelCategoryId(student.getPersonnelCategoryId());
                        militaryUser.setSecurityCardNo(student.getSecurityCardNo());
                        militaryUser.setMilitaryIdNo(student.getMilitaryIdNo());
                        militaryUser.setOrganizationalCategory(student.getOrganizationalCategory());
                        militaryUser.setDutyTitle(student.getDutyTitle());
                        user.setMilitaryUser(militaryUser);
                    }

                    // 设置用户类型为学生
                    user.setUserType("2");
                    // 设置学生角色
                    user.setRoleIds(studentRoleIds);
                    userService.updateUser(user);
                    // 简化成功消息，只包含账户信息和导入状态
                    String accountOrName = StringUtils.isNotEmpty(student.getUserName()) ? student.getUserName() : student.getNickName();
                    String successMsg = "账户:" + accountOrName + " ,导入成功";
                    importStatus.addSuccessMsg(index, successMsg);
                } else {
                    throw new GlobalException("账号{}已存在", student.getUserName());
                }
            } catch (Exception e) {
                // 增强错误记录，添加更多上下文信息
                String errorMsg = "第" + index + "行数据导入失败: ";
                if (StringUtils.isNotEmpty(student.getUserName())) {
                    errorMsg += "账号: " + student.getUserName();
                    // 同时添加姓名信息（如果存在）
                    if (StringUtils.isNotEmpty(student.getNickName())) {
                        errorMsg += "，姓名: " + student.getNickName();
                    }
                    errorMsg += ", ";
                } else if (StringUtils.isNotEmpty(student.getNickName())) {
                    // 如果只有姓名没有账号，也显示姓名
                    errorMsg += "姓名: " + student.getNickName() + ", ";
                }
                if (StringUtils.isNotEmpty(student.getIdentity())) {
                    errorMsg += "身份证号: " + student.getIdentity() + ", ";
                }
                if (StringUtils.isNotEmpty(student.getDeptName())) {
                    errorMsg += "部门: " + student.getDeptName() + ", ";
                }
                errorMsg += "错误原因: " + e.getMessage();
                // 简化失败消息，移除重复序号
                String account = StringUtils.isNotEmpty(student.getUserName()) ? student.getUserName() : student.getNickName();
                String failMsg = "账户:" + account + " ,导入失败，详情:" + e.getMessage();
                importStatus.addFailError(index, new ServiceException(failMsg));
                log.error(errorMsg, e);
            } finally {
                index++;
            }
        }
        return importStatus.toHtmlString();
    }


    @Override
    public List<StudentExcelVo> toExcelVo(List<SysUser> list) {
        Map<Long, String> baseMap = MapUtil.reverse(baseService.selectAllIdToMap());
        Map<Long, String> schoolMap = MapUtil.reverse(schoolService.selectAllIdToMap());
        return list.stream().map(u -> {
            StudentExcelVo studentExcelVo = BeanUtil.copyProperties(u, StudentExcelVo.class);
            studentExcelVo.setDeptName(u.getDept().getDeptName());
            studentExcelVo.setBase(MapUtil.get(baseMap, u.getUserInfo().getBase()));
            studentExcelVo.setSchool(MapUtil.get(schoolMap, u.getUserInfo().getSchool()));
            studentExcelVo.setPost(u.getUserInfo().getPost());

            // 映射军人表相关字段
            if (u.getMilitaryUser() != null) {
                studentExcelVo.setNation(u.getMilitaryUser().getNation());
                studentExcelVo.setNativePlace(u.getMilitaryUser().getNativePlace());
                studentExcelVo.setEnlistmentTime(u.getMilitaryUser().getEnlistmentTime());
                studentExcelVo.setPartyJoiningTime(u.getMilitaryUser().getPartyJoiningTime());
                studentExcelVo.setEnlistmentPlace(u.getMilitaryUser().getEnlistmentPlace());
                studentExcelVo.setEducationId(u.getMilitaryUser().getEducationId());
                studentExcelVo.setDegreeId(u.getMilitaryUser().getDegreeId());
                studentExcelVo.setBloodType(u.getMilitaryUser().getBloodType());
                studentExcelVo.setPersonnelCategoryId(u.getMilitaryUser().getPersonnelCategoryId());
                studentExcelVo.setSecurityCardNo(u.getMilitaryUser().getSecurityCardNo());
                studentExcelVo.setMilitaryIdNo(u.getMilitaryUser().getMilitaryIdNo());
                studentExcelVo.setOrganizationalCategory(u.getMilitaryUser().getOrganizationalCategory());
                studentExcelVo.setDutyTitle(u.getMilitaryUser().getDutyTitle());
            }

            return studentExcelVo;
        }).collect(Collectors.toList());
    }


}
